home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / game / role / ScottItal.lha / ScottItal / Src / SCOTT_A.C < prev    next >
C/C++ Source or Header  |  2002-10-26  |  15KB  |  657 lines

  1. /*
  2.  *  ScottFree Revision 1.14b
  3.  *
  4.  *
  5.  *  This program is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU General Public License
  7.  *  as published by the Free Software Foundation; either version
  8.  *  2 of the License, or (at your option) any later version.
  9.  *
  10.  *
  11.  *  You must have an ANSI C compiler to build this program.
  12.  *
  13.  *  ===================================================================
  14.  *
  15.  *  Version History AMIGA:
  16.  *  Ver ,     Date,     Author, Comment
  17.  *  -------------------------------------------------------------------
  18.  *  1.0 , 28/07/96, Andreas Aumayr, First public release
  19.  *  1.1 , 30/08/96, Andreas Aumayr, Minor changes for new amiga.c
  20.  *  1.2 , 30/10/02, Betori Alessandro, piccoli cambiamenti per
  21.  *  il corretto rilascio della memoria 
  22.  * 
  23.  *  ___________________________________________________________________
  24.  */
  25.  
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <ctype.h>
  31. #include <stdarg.h>
  32. #include <time.h>
  33.  
  34. #include "Scott.h"
  35. #include "ansi.c"
  36. #include "protos.h"
  37. #include "amiga6.c"
  38.  
  39. int OutputPos=0;
  40.  
  41. void *indirizzo_puntatore[1024];//Betori
  42.  
  43.  
  44. void Fatal(char *x)
  45. {
  46.     sprintf(str_buf,"\n\n%s!\n",x);
  47.     WriteCON(str_buf);
  48.     Delay(200);
  49.     close_all();
  50.     exit(1);
  51. }
  52.  
  53. void put_choice(void)
  54. {
  55.     if (RESTART) {
  56.         OutBuf("\nVuoi (R)icaricare, ri(C)ominciare or (F)inire il gioco? ");
  57.         Speak("Vuoi (R)icaricare, ri(C)ominciare or (F)inire il gioco?");
  58.     }
  59.     else {
  60.         OutBuf("\nVuoi (R)icaricare o (F)inire il gioco? ");
  61.         Speak("Vuoi (R)icaricare o (F)inire il gioco?");
  62.     }
  63.     cursor(TRUE);
  64. }
  65.  
  66. int RandomPercent(int n)
  67. {
  68.     unsigned int rv=rand()<<6;
  69.     rv=rv%100;
  70.     if(rv<n)
  71.         return(1);
  72.     return(0);
  73. }
  74.  
  75. int CountCarried()
  76. {
  77.     int ct=0;
  78.     int n=0;
  79.     while(ct<=GameHeader.NumItems)
  80.     {
  81.         if(Items[ct].Location==CARRIED)
  82.             n++;
  83.         ct++;
  84.     }
  85.     return(n);
  86. }
  87.  
  88. char *MapSynonym(char *word)
  89. {
  90.     int n=1;
  91.     char *tp;
  92.     static char lastword[16];   /* Last non synonym */
  93.     while(n<=GameHeader.NumWords)
  94.     {
  95.         tp=Nouns[n];
  96.         if(*tp=='*')
  97.             tp++;
  98.         else
  99.             strcpy(lastword,tp);
  100.         if(Strnicmp(word,tp,GameHeader.WordLength)==0)
  101.             return(lastword);
  102.         n++;
  103.     }
  104.     return(NULL);
  105. }
  106.  
  107. int MatchUpItem(char *text, int loc)
  108. {
  109.     char *word=MapSynonym(text);
  110.     int ct=0;
  111.  
  112.         if(word==NULL)
  113.         word=text;
  114.  
  115.     while(ct<=GameHeader.NumItems)
  116.     {
  117.         if(Items[ct].AutoGet && Items[ct].Location==loc &&
  118.             Strnicmp(Items[ct].AutoGet,word,GameHeader.WordLength)==0)
  119.             return(ct);
  120.         ct++;
  121.     }
  122.     return(-1);
  123. }
  124.  
  125. char *ReadString(FILE *f)
  126. {
  127.     char tmp[1024];
  128.     
  129.     char *t;
  130.     int c,nc;
  131.     int ct=0;
  132. oops:   do
  133.     {
  134.         c=fgetc(f);
  135.     }
  136.     while(c!=EOF && isspace(c));
  137.     if(c!='"')
  138.     {
  139.         Fatal("Iniziale apicetto atteso");
  140.     }
  141.     do
  142.     {
  143.         c=fgetc(f);
  144.         if(c==EOF)
  145.             Fatal("EOF nella stringa");
  146.         if(c=='"')
  147.         {
  148.             nc=fgetc(f);
  149.             if(nc!='"')
  150.             {
  151.                 ungetc(nc,f);
  152.                 break;
  153.             }
  154.         }
  155.         if(c==0x60)
  156.             c='"'; /* pdd */
  157.         tmp[ct++]=c;
  158.     }
  159.     while(1);
  160.     tmp[ct]=0;
  161.     t=MemAlloc(ct+1);// Alloca Memoria
  162.     memcpy(t,tmp,ct+1);
  163.     return(t);
  164. }
  165.  
  166. void NextLine()
  167. {
  168.     WriteCON("\n");
  169.     OutputPos = 0;
  170.     //OutReset();
  171. }
  172.  
  173. void Look()
  174. {
  175.     static char *ExitNames[6]=
  176.     {
  177.         "Nord","Sud","Est","Ovest","Alto","Basso"
  178.     };
  179.     Room *r;
  180.     int ct,f;
  181.     int pos;
  182.  
  183.     CON_handle = env_hdl;
  184.     clrscr();
  185.  
  186.     if ((BitFlags&(1L<<DARKBIT)) && Items[LIGHT_SOURCE].Location!= CARRIED
  187.        && Items[LIGHT_SOURCE].Location!= MyLoc) {
  188.         if (Options&YOUARE) {
  189.             WriteCON("Non puoi vedere. E' buio!\n");
  190.             Speak("Non puoi vedere. E' buio!");
  191.         }
  192.         else {
  193.             WriteCON("Non posso vedere.E' buio!\n");
  194.             Speak("Non posso vedere. E' buio!");
  195.         }
  196.         if (Options & TRS80_STYLE) WriteCON(TRS80_LINE);
  197.  
  198.         if (GFX && last_pic) {
  199.             if (LDP) Draw_Pic(0,0);
  200.             else Open_Pic(0,PIC);
  201.         }
  202.  
  203.         CON_handle = act_hdl;
  204.         return;
  205.     }
  206.  
  207.     r=&Rooms[MyLoc];
  208.     if(*r->Text=='*') {
  209.         sprintf(str_buf,"%s\n",r->Text+1);
  210.         OutBuf(str_buf);
  211.         Speak(str_buf);
  212.     }
  213.     else
  214.     {
  215.         if(Options&YOUARE) {
  216.             sprintf(str_buf,"Luogo: %s\n",r->Text);
  217.             OutBuf(str_buf);
  218.             Speak(str_buf);
  219.         }
  220.         else {
  221.             sprintf(str_buf,"Luogo: %s\n",r->Text);
  222.             OutBuf(str_buf);
  223.             Speak(str_buf);
  224.         }
  225.     }
  226.     ct=0;
  227.     f=0;
  228.     WriteCON("\nDirezioni ovvie: ");
  229.     Speak("Direzioni ovvie:");
  230.     while(ct<6)
  231.     {
  232.         if(r->Exits[ct]!=0)
  233.         {
  234.             if(f==0)
  235.                 f=1;
  236.             else
  237.                 WriteCON(", ");
  238.             WriteCON(ExitNames[ct]);
  239.             Speak(ExitNames[ct]);
  240.         }
  241.         ct++;
  242.     }
  243.     if(f==0) {
  244.         WriteCON("nessuna");
  245.         Speak("nessuna");
  246.     }
  247.     WriteCON(".\n");
  248.     ct=0;
  249.     f=0;
  250.     pos=0;
  251.     while(ct<=GameHeader.NumItems)
  252.     {
  253.         if(Items[ct].Location==MyLoc)
  254.         {
  255.             //printf("Item %d is in Room\n",ct);
  256.             if(f==0)
  257.             {
  258.                 if(Options&YOUARE) {
  259.                     WriteCON("\nPuoi anche vedere: ");
  260.                     Speak("Puoi anche vedere:");
  261.                 }
  262.                 else {
  263.                     WriteCON("\nPosso anche vedere: ");
  264.                     Speak("Posso anche vedere:");
  265.                 }
  266.                 pos=16;
  267.                 f++;
  268.             }
  269.             else if (!(Options & TRS80_STYLE))
  270.             {
  271.                 WriteCON(" - ");
  272.                 pos+=3;
  273.             }
  274.             if(pos+strlen(Items[ct].Text)>(Width-10))
  275.             {
  276.                 pos=0;
  277.                 WriteCON("\n");
  278.             }
  279.             WriteCON(Items[ct].Text);
  280.             Speak(Items[ct].Text);
  281.             pos += strlen(Items[ct].Text);
  282.             if (Options & TRS80_STYLE)
  283.             {
  284.                 WriteCON(". ");
  285.                 pos+=2;
  286.             }
  287.         }
  288.         ct++;
  289.     }
  290.     if (Options & TRS80_STYLE) WriteCON(TRS80_LINE);
  291.     if (GFX) Handle_Pic(MyLoc);
  292.     CON_handle = act_hdl;
  293. }
  294.  
  295. void LoadDatabase(FILE *f, int loud)
  296. {
  297.    
  298.     char buf[32];
  299.     int ni,na,nw,nr,mc,pr,tr,wl,lt,mn,trm;
  300.     int ct;
  301.     short lo;
  302.     Action *ap;
  303.     Room *rp;
  304.     Item *ip;
  305.   
  306.  
  307. /* Load the header */
  308.  
  309.     if(fscanf(f,"%*d %d %d %d %d %d %d %d %d %d %d %d",
  310.         &ni,&na,&nw,&nr,&mc,&pr,&tr,&wl,<,&mn,&trm,&ct)<10)
  311.         Fatal("File di avventura non valido (cattivo header)");
  312.     GameHeader.NumItems=ni;
  313.     Items=(Item *)MemAlloc(sizeof(Item)*(ni+1));
  314.     GameHeader.NumActions=na;
  315.     Actions=(Action *)MemAlloc(sizeof(Action)*(na+1));
  316.     GameHeader.NumWords=nw;
  317.     GameHeader.WordLength=wl;
  318.     Verbs=(char **)MemAlloc(sizeof(char *)*(nw+1));
  319.     Nouns=(char **)MemAlloc(sizeof(char *)*(nw+1));
  320.     GameHeader.NumRooms=nr;
  321.     Rooms=(Room *)MemAlloc(sizeof(Room)*(nr+1));
  322.     GameHeader.MaxCarry=mc;
  323.     GameHeader.PlayerRoom=pr;
  324.     GameHeader.Treasures=tr;
  325.     GameHeader.LightTime=lt;
  326.     LightRefill=lt;
  327.     GameHeader.NumMessages=mn;
  328.     Messages=(char **)MemAlloc(sizeof(char *)*(mn+1));
  329.     GameHeader.TreasureRoom=trm;
  330.     
  331. /* Load the actions */
  332.  
  333.     ct=0;
  334.     ap=Actions;
  335.     if(loud)
  336.         printf("Leggendo %d azioni.\n",na);
  337.     sprintf(buf,"Azioni:   %d\n",na);
  338.     strcat(GameInfoStr,buf);
  339.     while(ct<na+1)
  340.     {
  341.         if(fscanf(f,"%hd %hd %hd %hd %hd %hd %hd %hd",
  342.             &ap->Vocab,
  343.             &ap->Condition[0],
  344.             &ap->Condition[1],
  345.             &ap->Condition[2],
  346.             &ap->Condition[3],
  347.             &ap->Condition[4],
  348.             &ap->Action[0],
  349.             &ap->Action[1])!=8)
  350.         {
  351.             printf("Cattiva azione alla linea (%d)\n",ct);
  352.             exit(1);
  353.         }
  354.         ap++;
  355.         ct++;
  356.     }
  357.     ct=0;
  358.     if(loud)
  359.         printf("Leggendo %d paia di parole.\n",nw);
  360.     sprintf(buf,"Paia di parole: %d\n",nw);
  361.     strcat(GameInfoStr,buf);
  362.     while(ct<nw+1)
  363.     {
  364.         Verbs[ct]=ReadString(f);
  365.         Nouns[ct]=ReadString(f);
  366.         ct++;
  367.     }
  368.     ct=0;
  369.     rp=Rooms;
  370.     if(loud)
  371.         printf("Leggendo %d stanze.\n",nr);
  372.     sprintf(buf,"Stanze:      %d\n",nr);
  373.     strcat(GameInfoStr,buf);
  374.     while(ct<nr+1)
  375.     {
  376.         fscanf(f,"%hd %hd %hd %hd %hd %hd",
  377.             &rp->Exits[0],&rp->Exits[1],&rp->Exits[2],
  378.             &rp->Exits[3],&rp->Exits[4],&rp->Exits[5]);
  379.         rp->Text=ReadString(f);
  380.         ct++;
  381.         rp++;
  382.     }
  383.     ct=0;
  384.     if(loud)
  385.         printf("Leggendo %d messaggi.\n",mn);
  386.     sprintf(buf,"Messaggi:   %d\n",mn);
  387.     strcat(GameInfoStr,buf);
  388.     while(ct<mn+1)
  389.     {
  390.         Messages[ct]=ReadString(f);
  391.         ct++;
  392.     }
  393.     ct=0;
  394.     if(loud)
  395.         printf("Leggendo %d oggetti.\n",ni);
  396.     sprintf(buf,"Oggetti:      %d\n",ni);
  397.     strcat(GameInfoStr,buf);
  398.     ip=Items;
  399.     while(ct<ni+1)
  400.     {
  401.         ip->Text=ReadString(f);
  402.         ip->AutoGet=strchr(ip->Text,'/');
  403.         /* Some games use // to mean no auto get/drop word! */
  404.         if(ip->AutoGet && strcmp(ip->AutoGet,"//") && strcmp(ip->AutoGet,"/*"))
  405.         {
  406.             char *t;
  407.             *ip->AutoGet++=0;
  408.             t=strchr(ip->AutoGet,'/');
  409.             if(t!=NULL)
  410.                 *t=0;
  411.         }
  412.         fscanf(f,"%hd",&lo);
  413.         ip->Location=(unsigned char)lo;
  414.         ip->InitialLoc=ip->Location;
  415.         ip++;
  416.         ct++;
  417.     }
  418.     ct=0;
  419.     /* Discard Comment Strings */
  420.     while(ct<na+1)
  421.     {
  422.         ReadString(f);
  423.         ct++;
  424.     }
  425.     fscanf(f,"%d",&ct);
  426.     if(loud)
  427.         printf("Versione %d.%02d di Adventure ",ct/100,ct%100);
  428.     sprintf(buf,"Versione:  %d.%02d\n",ct/100,ct%100);
  429.     strcat(GameInfoStr,buf);
  430.     fscanf(f,"%d",&ct);
  431.     if(loud)
  432.         printf("%d.\nCaricamento completato.\n\n",ct);
  433.     sprintf(buf,"Game Nr.:   %2d",ct);
  434.     strcat(GameInfoStr,buf);
  435. }
  436.  
  437. void OutReset()
  438. {
  439.     OutputPos=0;
  440.     gotoxy(1,BottomHeight);
  441.     clreol();
  442. }
  443.  
  444. void OutBuf(char *buffer)
  445. {
  446.     char word[80];
  447.     int wp,len;
  448.  
  449.     len = strlen(buffer);
  450.     while(*buffer)
  451.     {
  452.         if(OutputPos==0)
  453.         {
  454.             while(*buffer && isspace(*buffer))
  455.             {
  456.                 if (*buffer=='\n') NextLine();
  457.                 buffer++;
  458.             }
  459.         }
  460.         if(*buffer==0) {
  461.             return;
  462.         }
  463.         wp=0;
  464.         while(*buffer && ((!isspace(*buffer)) || (*(buffer-1) == '*') || (*(buffer+1) == '*')))
  465.         {
  466.             word[wp++]=*buffer++;
  467.         }
  468.         word[wp]=0;
  469.  
  470.         //printf("Parola '%s' a %d\n",word,OutputPos);
  471.  
  472.         if (LINEWRAP) {
  473.             if ((OutputPos + strlen(word) > Width - 2)  && (*word != '.')) NextLine();
  474.             OutputPos += strlen(word);
  475.         }
  476.         else {
  477.             if (((OutputPos + strlen(word) > Width - 2)  && (*word != '.') && (len <= Width)) || (OutputPos == Width)) NextLine();
  478.             OutputPos += strlen(word);
  479.             if (OutputPos >= Width) OutputPos -= Width;
  480.         }
  481.  
  482.         WriteCON(word);
  483.         
  484.         if(*buffer==0) {
  485.             return;
  486.         }
  487.  
  488.         if (*buffer=='\n') NextLine();
  489.         else
  490.         {
  491.             OutputPos++;
  492.             if(OutputPos < (Width-1))
  493.                 WriteCON(" ");
  494.         }
  495.         buffer++;
  496.     }
  497. }
  498.  
  499. void OutputScott(char *a)
  500. {
  501.     char block[512];
  502.     strcpy(block,a);
  503.     OutBuf(block);
  504. }
  505.  
  506. void OutputNumber(int a)
  507. {
  508.     char buf[16];
  509.     sprintf(buf,"%d ",a);
  510.     OutBuf(buf);
  511. }
  512.  
  513. void GetInput(int *vb, int *no)
  514. {
  515.     char buf[256];
  516.     char verb[10],noun[10];
  517.     int vc,nc;
  518.     int num;
  519.  
  520.     do
  521.     {
  522.         do
  523.         {
  524.             OutputScott("Cosa devo fare ? ");
  525.             Speak("Cosa devo fare?");
  526.             cursor(TRUE);
  527.             LineInput2(buf);
  528.             Speak(buf);
  529.             cursor(FALSE);
  530.             OutReset();
  531.             num=sscanf(buf,"%9s %9s",verb,noun);
  532.         }
  533.         while(num==0||*buf=='\n'||*buf==0);
  534.         //printf("%d, %s, %s\n",num,verb,noun);
  535.         if(num==1)
  536.             *noun=0;
  537.         if(*noun==0 && strlen(verb)==1)
  538.         {
  539.             switch(isupper(*verb)?tolower(*verb):*verb)
  540.             {
  541.                 case 'n':strcpy(verb,"NORD");break;
  542.                 case 'e':strcpy(verb,"EST");break;
  543.                 case 's':strcpy(verb,"SUD");break;
  544.                 case 'o':strcpy(verb,"OVEST");break;
  545.                 case 'a':strcpy(verb,"ALTO");break;
  546.                 case 'b':strcpy(verb,"BASSO");break;
  547.                 /* Brian Howarth interpreter also supports this */
  548.                 case 'i':strcpy(verb,"INVENTARIO");break;
  549.                 /* AMIGA interpreter extension */
  550.                 case 'g':strcpy(verb,"GUARDA");break;
  551.             }
  552.         }
  553.         nc=WhichWord(verb,Nouns);
  554.         /* The Scott Adams system has a hack to avoid typing 'go' */
  555.         if(nc>=1 && nc <=6)
  556.         {
  557.             vc=1;
  558.         }
  559.         else
  560.         {
  561.             vc=WhichWord(verb,Verbs);
  562.             nc=WhichWord(noun,Nouns);
  563.         }
  564.         *vb=vc;
  565.         *no=nc;
  566.         if(vc==-1)
  567.         {
  568.             OutputScott("\"");
  569.             OutputScott(verb);
  570.             Speak(verb);
  571.             OutputScott("\" è una parola che non conosco... spiacente!\n");
  572.             Speak("\" è una parola che non conosco. Spiacente!");
  573.         }
  574.     }
  575.     while(vc==-1);
  576.     strcpy(NounText,noun);  /* Needed by GET/DROP hack */
  577. }
  578.  
  579. void SaveGame(void)
  580. {
  581.     FILE *f;
  582.  
  583.     if (Open_ASL(save_game,save_dir,1) == FALSE) {
  584.         OutputScott("Save game cancellato.\n");
  585.         Speak("Save game cancellato.");
  586.         return;
  587.     }
  588.     Make_FFP(save_game,save_dir);
  589.     f=fopen(FFP,"w");
  590.     if(f==NULL)
  591.     {
  592.         sprintf(str_buf,"Impossibile creare il file di salvataggio '%s'.\n",FFP);
  593.         OutputScott(str_buf);
  594.         Speak("Impossibile creare il file di salvataggio ");
  595.         return;
  596.     }
  597.     SaveBody(f);
  598.     sprintf(str_buf,"Gioco salvato '%s'.\n",FFP);
  599.     OutputScott(str_buf);
  600.     Speak("Gioco salvato.");
  601.     return;
  602. }
  603.  
  604. BOOL LoadGame(char *name)
  605. {
  606.     FILE *f=fopen(name,"r");
  607.  
  608.     if(f==NULL)
  609.     {
  610.         sprintf(str_buf,"Impossibile ricaricare il gioco '%s'.\n\n",name);
  611.         OutputScott(str_buf);
  612.         Speak("Impossibile ricaricare il gioco.");
  613.         return(TRUE);
  614.     }
  615.     LoadBody(f);
  616.     sprintf(str_buf,"Gioco ricaricato '%s'.\n",name);
  617.     OutputScott(str_buf);
  618.     Speak("Gioco ricaricato.");
  619.     return(FALSE);
  620. }
  621.  
  622. BOOL RestoreGame()
  623. {
  624.     if (Open_ASL(save_game,save_dir,0) == FALSE) return(TRUE);
  625.     Make_FFP(save_game,save_dir);
  626.     return(LoadGame(FFP));
  627. }
  628.  
  629. int WhichWord(char *word, char **list)
  630. {
  631.     int n=1;
  632.     int ne=1;
  633.     char *tp;
  634.  
  635.     /* quick & dirty workaround for missing feature 'RESTORE'
  636.        no more need for quit/restart game. */
  637.     if(Strnicmp(word,"!RICARICA",GameHeader.WordLength)==0) {
  638.         RestoreGame();
  639.         strcpy(word,"GUARDA");
  640.         Redraw = 1;
  641.     }
  642.  
  643.     while(ne<=GameHeader.NumWords)
  644.     {
  645.         tp=list[ne];
  646.         if(*tp=='*')
  647.             tp++;
  648.         else
  649.             n=ne;
  650.         if(Strnicmp(word,tp,GameHeader.WordLength)==0)
  651.             return(n);
  652.         ne++;
  653.     }
  654.     return(-1);
  655. }
  656.  
  657.